package Organisation;

import java.util.StringTokenizer;

import jade.core.AID;
import jade.core.behaviours.Behaviour;
import jade.lang.acl.ACLMessage;
import Inspector.AgentInspector2;
import Environnement.Arete;
import Environnement.Chemin;
import Environnement.Graph;
import Environnement.Noeud;
import Environnement.Percepts;
import Environnement.Util;
import eis.iilang.Action;
/**
 * TODO description
 */
public class BehaviourIns2 extends Behaviour {

	public BehaviourIns2()
	{
		
	}
	
	public void action()
	{
		
		
		AgentInspector2 agent = (AgentInspector2)getAgent();
		if(agent.isVerbose())
			agent.println("Debut Action");
		checkPercept();
		checkMessage();
		checkHealth();
		Action act = rech();
		if(agent.isVerbose())
			agent.println("Rech");
		try{
			if(act != null)
			{
				agent.performAction(act);
				return;
			}
			checkVis();
			
			act = walk();
			if(agent.isVerbose())
				agent.println("Walk");
			if(act != null)
			{
				agent.performAction(act);
				return;
			}
			if(agent.isVerbose())
				agent.println("Rech");
			agent.performAction(Util.rechargeAction());
		}
		catch(Exception e)
		{
			System.err.println(e.getMessage());
		}
		
	}
	
	public void checkPercept()
	{
		AgentInspector2 agent = (AgentInspector2)getAgent();
		Graph graph = agent.getGraph();
		boolean succes = false;
		boolean inspect = false;
		
		for(Percepts p : agent.getAllPercept())
		{
			
			if(p.getName().equals("position"))
			{
				String pos = p.getValues().get(0);
				if(graph.getNoeud(pos) != null)
					graph.getNoeud(pos).setVisite(true);
				else
				{
					Noeud n = new Noeud(pos);
					n.setVisite(true);
					graph.addNoeud(n);
				}
					
			}
			else if ( p.getName().equals("visibleEdge") ) 
			{	
				for(String s : p.getValues())
				{
					StringTokenizer tk = new StringTokenizer(s);
					String vertex1 = tk.nextToken();
					String vertex2 = tk.nextToken();
					Noeud ver1, ver2;
					
					if(!graph.isPresent(vertex1))
					{
						agent.addGoal("EdgeAVis-"+vertex1);
						ver1 = new Noeud(vertex1);
						graph.addNoeud(ver1);
						
					}
					else
					{
						ver1 = graph.getNoeud(vertex1);
					}
					if(!graph.isPresent(vertex2))
					{
						agent.addGoal("EdgeAVis-"+vertex2);
						ver2 = new Noeud(vertex2);
						graph.addNoeud(ver2);
					}
					else
					{
						ver2 = graph.getNoeud(vertex2);
					}		
					
					boolean add = false;
					
					for(Arete a : ver1.getAretes())
					{
						if(a.getArrive() == ver2 )
							add = true;
					}
					
					if(add == false)
					{
						ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
						msg.setConversationId("Noeud");
						msg.setContent(vertex1+" "+vertex2);
						AID[] receiver =agent.getTeamAID(); 
						for(int i = 0; i<receiver.length;i++)
							msg.addReceiver(receiver[i]);
						ver1.addNoeud(ver2, 1);
						agent.send(msg);
					}
				}
				
			}
			else if(p.getName().equals("lastActionResult"))
			{
				if(p.getValues().get(0).equals("successful"))
					succes = true;
					
			}else if(p.getName().equals("lastAction"))
			{
				if(p.getValues().get(0).equals("inspect"))
					inspect = true;
			}
			
	
		if(inspect && succes)
				agent.removeGoal("inspect");
		}
	}
	
	public Action rech()
	{
		AgentInspector2 agent = (AgentInspector2)getAgent();
		
		if ( agent.getPercepts("energy") == null ) {
			if(agent.isVerbose())
				agent.println("Probleme je connais pas mon energy");
			return null;
		}
		
		double min = 0.1;
		int energy = Integer.parseInt(agent.getPercepts("energy").getValues().get(0));
		int max = Integer.parseInt(agent.getPercepts("maxEnergy").getValues().get(0)) ;
		if( energy < min * max) 
		{
			if(agent.isVerbose())
				agent.println("Recharge -> energy : "+energy);
			return Util.rechargeAction();
		}

		if(agent.getPercepts("lastActionResult").getValues().get(0).equals("failed_resources"))
		{
			if(agent.getPercepts("lastAction").getValues().get(0).equals("probe"))
				agent.addGoal("Probe");
			return Util.rechargeAction();
		}
		
		return null;
		

	}
	
	public void checkVis()
	{
		AgentInspector2 agent = (AgentInspector2)getAgent();
		Percepts p = agent.getPercepts("inspectedEntity");
		if(p == null)
			return;
		String pos =agent.getPercepts("position").getValues().get(0);
		for(String ent : p.getValues())
		{
			
			StringTokenizer tk = new StringTokenizer(ent);
			String name = tk.nextToken();
			if(tk.nextToken().equals(agent.getTeamName()))
				continue;
			String role = tk.nextToken();
			agent.addBelief("ennemies",name+" "+role);
			
			ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
			msg.setConversationId("InfoEntity");
			msg.setContent(name+" "+role+" "+pos);
			AID[] receiver =agent.getTeamAID(); 
			for(int i = 0; i<receiver.length;i++)
				msg.addReceiver(receiver[i]);
			agent.send(msg);
		}
	}
	
	public Action walk()
	{
		AgentInspector2 agent = (AgentInspector2)getAgent();
		Chemin ch = agent.getChemin();
		String dest = null;
		String pos = agent.getPercepts("position").getValues().get(0);
		int size = Integer.parseInt(agent.getPercepts("visRange").getValues().get(0));
		if(agent.isVerbose())
			agent.println("Debut Walk");
		if(ch.getDernierNoeud().equals(pos))
		{
			ch = agent.getGraph().findNoeud(pos);
			if(ch == null)
				return null;
			dest = ch.getListNoeud().get(0);
			agent.setChemin(ch);
		}
		else
		{
			for(int i = 1; i< ch.getListNoeud().size()-1;i++)
				if(ch.getListNoeud().get(i).equals(pos))
					dest = ch.getListNoeud().get(i+1);
		}
		if(dest !=null)
		{
			if(agent.isVerbose())
				agent.println("Prochaine destination "+dest);
			return Util.gotoAction(dest);
		}
		else
		{
			if(agent.isVerbose())
				agent.println("Dest New");
			ch = agent.getGraph().findNoeud(pos);
			if(ch != null)
			{
				dest = ch.getListNoeud().get(0);
				agent.setChemin(ch);
				return Util.gotoAction(dest);
			}
			
		}
		if(agent.isVerbose())
			agent.println("Probleme pour trouver une nouvelle destination");
		return null;
		
	}
	
	public void checkMessage()
	{
		
		AgentInspector2 agent = (AgentInspector2)getAgent();
		ACLMessage msg = agent.receive();
		Graph graph = agent.getGraph();
		
		while(msg != null)
		{
			String id =msg.getConversationId(); 
			if(id.equals("Noeud"))
			{
				StringTokenizer tk = new StringTokenizer(msg.getContent());
				
				String s1= tk.nextToken();
				String s2 = tk.nextToken();
				Noeud n1 = null;
				Noeud n2 = null;
				
				if(!graph.isPresent(s1))
				{
					n1 = new Noeud(s1);
					graph.addNoeud(n1);
				}
				else
					n1 = graph.getNoeud(s1);
				boolean find = false;
				
				for(Arete a: n1.getAretes())
					if(a.getArrive().getName().equals(s2))
					{
						find = true;
						break;
					}
				
				if(!find)
				{
					if(agent.isVerbose())
						agent.println("  Add Noeud --> "+msg.getContent());
					if(!graph.isPresent(s2))
					{
						n2 = new Noeud(s2);
						n1.addNoeud(n2,1);
						graph.addNoeud(n2);
					}
					else
						n1.addNoeud(graph.getNoeud(s2),1);
				}
						
			}
			else if(id.equals("Update"))
			{
				StringTokenizer tk = new StringTokenizer(msg.getContent());
				
				String s1= tk.nextToken();
				String s2 = tk.nextToken();
				int poids = Integer.parseInt(tk.nextToken());
				
				Noeud n1 = null;
				Noeud n2 = null;
				
				if(!graph.isPresent(s1))
				{
					n1 = new Noeud(s1);
					graph.addNoeud(n1);
				}
				else
					n1 = graph.getNoeud(s1);
				boolean find = false;
				
				for(Arete a: n1.getAretes())
					if(a.getArrive().getName().equals(s2))
					{
						find = true;
						break;
					}
				
				if(!find)
				{
					if(agent.isVerbose())
						agent.println("  Add Noeud --> "+msg.getContent());
					if(!graph.isPresent(s2))
					{
						n2 = new Noeud(s2);
						n1.addNoeud(n2,1);
						graph.addNoeud(n2);
					}
					else
						n1.addNoeud(graph.getNoeud(s2),1);
				}
				Arete a1 = null;
				for(Arete a: n1.getAretes())
					if(a.getArrive().getName().equals(s2))
					{
						a1 =a;
					}
				a1.setPoids(poids);
			}
			msg =agent.receive();
		}
	}
	
	public void checkHealth()
	{
		AgentBase agent = (AgentBase)getAgent();
		String enr = agent.getPercepts("health").getValues().get(0);
		String maxEnr = agent.getPercepts("maxHealth").getValues().get(0);
		if(!enr.equals(maxEnr))
		{	
			ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
			msg.setConversationId("Repair");
			msg.setContent(agent.getName());
			AID[] receiver =agent.getTeamAID(); 
			for(int i = 0; i<receiver.length;i++)
				msg.addReceiver(receiver[i]);
			agent.send(msg);
		}
		else
		{
			ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
			msg.setConversationId("Repaired");
			msg.setContent(agent.getName());
			AID[] receiver =agent.getTeamAID(); 
			for(int i = 0; i<receiver.length;i++)
				msg.addReceiver(receiver[i]);
			agent.send(msg);
		}
	}
	
	public boolean done()
	{
		return false;
	}
}